package day9;

//synchronized修饰方法 和 静态方法
public class Demo {
    //普通方法
    //public void printA(){
    //同步方法：同一个对象 同步方法 都是同一把锁(当前对象this)
    public synchronized void printA() {
        String name = Thread.currentThread().getName();
        System.out.println(name + "开始执行A方法");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(name + "结束执行A方法");
    }

    //同步方法
    public synchronized void printB() {
        String name = Thread.currentThread().getName();
        System.out.println(name + "开始执行B方法");
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(name + "结束执行B方法");
    }

    //静态同步方法：锁的不是this 是 当前对象的类对象(Demo.class)
    public synchronized static void printC() {
        String name = Thread.currentThread().getName();
        System.out.println(name + "开始执行C方法");
        try {
            Thread.sleep(300);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(name + "结束执行C方法");
    }

    public synchronized static void printD() {
        String name = Thread.currentThread().getName();
        System.out.println(name + "开始执行D方法");
        try {
            Thread.sleep(300);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(name + "结束执行D方法");
    }

    public static void main(String[] args) {
        Demo d1 = new Demo();
        Demo d3 = new Demo();
        //Demo2 d2 = new Demo2();
        //A和B线程两者调用的都是同步方法，锁的是当前的this
        //他们属于同一把锁 所以A方法没有执行结束 B方法需要等待执行
        //C和D线程两者调用的静态同步方法，锁的是类对象Demo.class
        //他们也属于同一把锁 所以C方法没有执行结束 D方法需要等待执行
        new Thread(() -> {
            d1.printA();
        }, "AAA").start();
        new Thread(() -> {
            d1.printB();//this-->d
        }, "BBB").start();
        new Thread(() -> {
            d1.printC();//类对象->Demo.class
        }, "CCC").start();
        new Thread(() -> {
            d3.printD();//类对象->Demo.class
        }, "DDD").start();
    }
}

class Demo2 {
    public synchronized void printB() {
        String name = Thread.currentThread().getName();
        System.out.println(name + "开始执行B方法");
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(name + "结束执行B方法");
    }
}
